package jast;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.TokenStreamRewriter;

import parser.JavaParser;
/**
 * 
 * @author FJC
 * 程序插桩
 */
public class StubListener extends JavaBaseListener {
	TokenStreamRewriter rewriter;
	private int index;
	public StubListener(TokenStream tokens){
		rewriter = new TokenStreamRewriter(tokens);
		index = 0;
	}
	
	public void enterTypeDeclaration(JavaParser.TypeDeclarationContext ctx) { 
		if(ctx.children.get(0) instanceof JavaParser.ClassOrInterfaceModifierContext){
			if(ctx.children.get(1) instanceof JavaParser.ClassDeclarationContext){
				rewriter.insertBefore(ctx.start, "import path.PathRec;\r\n");
			}
		}
	}

	public void enterClassBody(JavaParser.ClassBodyContext ctx) { 
		rewriter.insertAfter(ctx.start, "\r\npublic static PathRec path = new PathRec();");
	}
	
	public void enterStatement(JavaParser.StatementContext ctx) {
		String firstLabel = ctx.children.get(0).getText();
		if(firstLabel.equals("if")){
			index++;
			JavaParser.StatementContext sctx = (JavaParser.StatementContext)ctx.children.get(2); //statement
			if(sctx.children.get(0) instanceof JavaParser.BlockContext){
				JavaParser.BlockContext bctx = (JavaParser.BlockContext)sctx.children.get(0);
				if(bctx.start.getText().equals("{"))
					rewriter.insertAfter(bctx.start, "\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);");
			}
			//无{}的情况，添加{}
			else{
				rewriter.insertBefore(sctx.start, "{\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);\r\n");
				rewriter.insertAfter(sctx.stop, "\r\n}");
			}
			//else
			if(ctx.children.size()>3&&ctx.children.get(3).getText().equals("else")){
				sctx = (JavaParser.StatementContext)ctx.children.get(4); //statement
				if(sctx.start.getText().endsWith("{")){
					rewriter.insertAfter(sctx.start, "\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"1);");
				}else{
					rewriter.insertBefore(sctx.start, "{\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"1);\r\n");
					rewriter.insertAfter(sctx.stop, "\r\n}");
				}
			}
		}
		else if(firstLabel.equals("for")){
			index++;
			JavaParser.StatementContext sctx = (JavaParser.StatementContext)ctx.children.get(4); //statement
			if(sctx.children.get(0) instanceof JavaParser.BlockContext){
				JavaParser.BlockContext bctx = (JavaParser.BlockContext)sctx.children.get(0);
				if(bctx.start.getText().equals("{"))
					rewriter.insertAfter(bctx.start, "\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);");
				
			}
			//无{}的情况，添加{}
			else{
				rewriter.insertBefore(sctx.start, "{\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);\r\n");
				rewriter.insertAfter(sctx.stop, "\r\n}");
			}
		}
		else if(firstLabel.equals("while")){
			index++;
			JavaParser.StatementContext sctx = (JavaParser.StatementContext)ctx.children.get(2); //statement
			if(sctx.children.get(0) instanceof JavaParser.BlockContext){
				JavaParser.BlockContext bctx = (JavaParser.BlockContext)sctx.children.get(0);
				if(bctx.start.getText().equals("{"))
					rewriter.insertAfter(bctx.start, "\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);");
				
			}
			//无{}的情况，添加{}
			else{
				rewriter.insertBefore(sctx.start, "{\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);\r\n");
				rewriter.insertAfter(sctx.stop, "\r\n}");
			}
		}
		else if(firstLabel.equals("do")){
			index++;
			JavaParser.StatementContext sctx = (JavaParser.StatementContext)ctx.children.get(1); //statement
			if(sctx.children.get(0) instanceof JavaParser.BlockContext){
				JavaParser.BlockContext bctx = (JavaParser.BlockContext)sctx.children.get(0);
				if(bctx.start.getText().equals("{"))
					rewriter.insertAfter(bctx.start, "\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);");
			}
			//无{}的情况，添加{}
			else{
				rewriter.insertBefore(sctx.start, "{\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+"0);\r\n");
				rewriter.insertAfter(sctx.stop, "\r\n}");
			}
		}
		else if(firstLabel.equals("switch")){
			index++;
			int tmpCnt = 0;
			for(int i=3;i<ctx.children.size()-1;i++){
				if(ctx.children.get(i) instanceof JavaParser.SwitchBlockStatementGroupContext){
					JavaParser.SwitchBlockStatementGroupContext sctx = (JavaParser.SwitchBlockStatementGroupContext)ctx.children.get(i);
					JavaParser.BlockStatementContext bctx = null;
					for(int j=0;j<sctx.children.size();j++)
						if(sctx.children.get(j) instanceof JavaParser.BlockStatementContext){
							bctx = (JavaParser.BlockStatementContext)sctx.children.get(j);
							break;
						}
					if(bctx.start.getText().equals("{"))
						rewriter.insertAfter(bctx.start, "\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+(tmpCnt++)+");");
					else{
						rewriter.insertBefore(bctx.start, "{\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+(tmpCnt++)+");");
						rewriter.insertAfter(sctx.stop, "\r\n}");
					}
				}else{
					JavaParser.SwitchLabelContext sctx= (JavaParser.SwitchLabelContext)ctx.children.get(i);
					rewriter.insertAfter(sctx.start, "{\r\npath.addBranchNode(\"ClassName\", \"MethodName\", "+index+", "+(tmpCnt++)+");}\r\n");
				}
			}
		}
	}
	
	public void exitStatement(JavaParser.StatementContext ctx) {
		
	}
}